package hxy.bytecode.algorithm.IBM;

import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import java.util.Vector;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.SynchronousQueue;

public class Basic {

	public static void main(String[] args) {

		// First:dispatcher Service

		Dispather dispather = new Basic().new Dispather();

		new Thread(dispather).start();

		// Then : consumption

		// Multi-thread
		// 1.Thread pool
		// 2. simple multi-thread

		// Final : product

		while (true) {

			try {
				Thread.sleep((long) (Math.random() * 2000));
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}

			char c = ' ';
			int x = (int) (1 + Math.random() * 3);

			switch (x) {
			case 1:
				c = 'A';
				break;
			case 2:
				c = 'B';
				break;
			case 3:
				c = 'C';
				break;
			default:
				break;
			}

			new Thread(new Basic().new Submitter(dispather, c)).start();

		}

	}

	class Dispather implements Runnable {
		
		private BlockingQueue<Character> bq = new LinkedBlockingDeque<Character>();


		public void put(Character c) {
				try {
					bq.put(c);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
		}

		@Override
		public void run() {
			

			while (true) {

				Character character = null;
				if (bq != null) {

					while (!bq.isEmpty()) {

						try {
							character = bq.take();
						} catch (InterruptedException e) {
							
							e.printStackTrace();
						}

						switch (character) {
						case 'A':
							new Thread(new Basic().new HandlerA('A')).start();
							break;
						case 'B':
							new Thread(new Basic().new HandlerB('B')).start();
							break;
						case 'C':
							new Thread(new Basic().new HandlerC('C')).start();
							break;

						default:
							break;
						}

					}
				} else
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						
						e.printStackTrace();
					}

			}

		}
	}

	class Submitter implements Runnable {

		Dispather dispather;
		char c;

		public Submitter(Dispather dispather, char c) {

			this.dispather = dispather;
			this.c = c;

		}

		@Override
		public void run() {

			dispather.put(c);
			System.out.format("Submitter%c\n", c);

		}

	}

	class HandlerA implements Runnable {
		char c;

		public HandlerA(char c) {
			
			this.c = c;
		}

		@Override
		public void run() {
			
			System.out.format("Hander%c\n", c);
		}

	}

	class HandlerB implements Runnable {
		char c;

		public HandlerB(char c) {
			
			this.c = c;
		}

		@Override
		public void run() {
			
			System.out.format("Hander%c\n", c);
		}

	}

	class HandlerC implements Runnable {
		char c;

		public HandlerC(char c) {
			
			this.c = c;
		}

		@Override
		public void run() {
			
			System.out.format("Hander%c\n", c);

		}

	}

}
